import java.util.*;

enum TypeId { INT, CHAR, VOID,
          INT_ARR, CHAR_ARR,  
          INT_FUN, CHAR_FUN, VOID_FUN }

public class Type
{    
    protected TypeId id;

    public Type (TypeId _id) 
    {
	id = _id;
    }

   
    /* TODO
    public boolean isConvertable(Type from, Type to)
    {
	switch(from.id)
	{
	 case CHAR:
	     if(to.id == INT)
		 return true;
             break;

	}
    }
    */

    public String toString()
    {
	return "Type id: " + id;
    }

    public TypeId getId()
    {
	return id;
    }

}

class IntType extends Type{
    public IntType()
    {
	super(TypeId.INT);
    }
}

class CharType extends Type
{
    public CharType()
    {
	super(TypeId.CHAR);
    }
}

class VoidType extends Type{
    //Only to be used as a return type of a function call.
    public VoidType()
    {
	super(TypeId.VOID);
    }
}


class ArrayType extends Type
{
    int size;

    public ArrayType(TypeId id, int _size)
    {
	super(id);
	size = _size;
    }

    public String toString()
    {
	String response = "Type id: " + id + " size: " + size;	
	return response;
    }

    public int getSize()
    {
	return size;
    }
    

}

class IntArrayType extends ArrayType
{

    public IntArrayType(int _size)
    {
	super(TypeId.INT_ARR, _size);
    }

    public IntArrayType()
    {
	super(TypeId.INT_ARR, 0);
    }

}


class CharArrayType extends ArrayType
{

    public CharArrayType(int _size)
    {
	super(TypeId.CHAR_ARR, _size);
    }

    public CharArrayType()
    {
	super(TypeId.CHAR_ARR, 0);
    }
}

class FunctionType extends Type
{

    private List<Type> parameters;

    public FunctionType(List<Type> _parameters, TypeId id)
    {
	super(id);
	parameters = _parameters;
    }

    public String toString()
    {
	String response = "Type id: " + id +" (parameters: ";
	int n = parameters.size();
	for(int i = 0; i<n ; i++)
	{
	    response += parameters.get(i).toString();
	}
	response += ")";
	return response;
    }

    public List<Type> getParameters()
    {
	return parameters;
    }

}


class IntFunctionType extends FunctionType
{

    public IntFunctionType(List<Type> _parameters)
    {
	super(_parameters, TypeId.INT_FUN);	
    }
}

class CharFunctionType extends FunctionType
{
    public CharFunctionType(List<Type> _parameters)
    {
	super(_parameters, TypeId.CHAR_FUN);	
    }

}

class VoidFunctionType extends FunctionType
{

    public VoidFunctionType(List<Type> _parameters)
    {
	super(_parameters, TypeId.VOID_FUN);	
    }

}
